#include <Cocoa/Cocoa.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include "gl_saver.h"
#include "std.h"
#include "Smoke.h"
#include "Star.h"
#include "Spark.h"
#include "Particle.h"

// some globals
long TimeFreq, TimeStart;
double fTime = 0.0f;
//double fTimeOffset;
double TICKSPERSECOND = 12.0f;
double dframe = 0.0;
//int  gratuitousFlareMode = 0;
float drag;
double fDeltaTime;
double fOldTime;
float gravity = 1500000.0f;

Particle p[MAXNUMPARTICLES];
int numParticles = 250;
Smoke s;
Star star;
Spark spark[64];
float starfieldColor[MAXNUMPARTICLES*4*4];
float starfieldVertices[MAXNUMPARTICLES*2*4];
float starfieldTextures[MAXNUMPARTICLES*2*4];
int starfieldColorIndex;
int starfieldVerticesIndex;
int starfieldTexturesIndex;

//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Do any initialization of the rendering context here, such as
// setting background colors, setting up lighting, or performing
// preliminary calculations.
void GLSetupRC(void)
{
	int i;
	
	fOldTime = [NSDate timeIntervalSinceReferenceDate];
	
	spark[0].mystery = 1800 / 13;
	spark[1].mystery = (1800 * 2) / 13;
	spark[2].mystery = (1800 * 3) / 13;
	spark[3].mystery = (1800 * 4) / 13;
	spark[4].mystery = (1800 * 5) / 13;
	spark[5].mystery = (1800 * 6) / 13;
	spark[6].mystery = (1800 * 7) / 13;
	spark[7].mystery = (1800 * 8) / 13;
	spark[8].mystery = (1800 * 9) / 13;
	spark[9].mystery = (1800 * 10) / 13;
	spark[10].mystery = (1800 * 11) / 13;
	spark[11].mystery = (1800 * 12) / 13;
	for (i=0;i<NUMSMOKEPARTICLES;i++)
	{
		s.p[i].dead = TRUE;
	}

//	HDC hDC = GetDC(hWnd);
	
	// setup the defaults for OpenGL
	glDisable(GL_DEPTH_TEST);
//	glAlphaFunc(GL_GREATER,0.03125f);
	glAlphaFunc(GL_GREATER,0.0f);
	glEnable(GL_ALPHA_TEST);
	glShadeModel(GL_FLAT);
//	glEnable(GL_DITHER);
	glDisable(GL_LIGHTING);
	glDisable(GL_CULL_FACE);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
	glEnable(GL_BLEND);
	glViewport(0,0,(int) sys_glWidth,(int) sys_glHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-0.5,sys_glWidth+0.5,-0.5,sys_glHeight+0.5);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClear(GL_COLOR_BUFFER_BIT);
//	SwapBuffers(hDC);
//	glClear(GL_COLOR_BUFFER_BIT);
	//	ReleaseDC(hWnd, hDC );
	sys_Time = 0;
		
	for (i=0;i<12;i++)
	{
		spark[i].Update();
	}
	glEnableClientState(GL_COLOR_ARRAY);	
	glEnableClientState(GL_VERTEX_ARRAY);	
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Render the OpenGL Scene here. Called by the WM_PAINT message
// handler.
void GLRenderScene(void)
{
	static NSDate *oldDate = NULL;
	int i;
	dframe++;
	
	//GetMouse(&mouse);
	MouseX = 0;//mouse.h;
	MouseY = 0;//mouse.v;
	
	MouseDown = 0;//Button();
	
	//
	
	if (!oldDate)
		oldDate = [[NSDate date] retain];
	
	fOldTime = fTime;
	fTime = -[oldDate timeIntervalSinceNow];
	fDeltaTime = fTime - fOldTime;
	
	//NSLog(@"fTime = %f fDeltaTime = %f", fTime, fDeltaTime);
	
	drag = (float) pow(0.9965,fDeltaTime*85.0);
	
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0.0,0.0,0.0,5.0 * fDeltaTime);
	glRectd(-1,-1,sys_glWidth+1,sys_glHeight+1);
	
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
	
	for (int i=0;i<numParticles;i++)
	{
		p[i].Update();
	}
	star.Update();
	for (i=0;i<numStreams;i++)
	{
		spark[i].Update();
	}
	s.Update();
	//if ((fTime - fTimeOffset) > 0.05f)
	{
		glEnable(GL_TEXTURE_2D);
		s.Draw();
		/*glBegin(GL_QUADS);
		starfieldColorIndex = 0;
		starfieldVerticesIndex = 0;
		starfieldTexturesIndex = 0;
		for (i=0;i<numParticles;i++)
		{
			p[i].Draw();
		}
		glColorPointer(4,GL_FLOAT,0,starfieldColor);
		glVertexPointer(2,GL_FLOAT,0,starfieldVertices);
		glTexCoordPointer(2,GL_FLOAT,0,starfieldTextures);
 		glDrawArrays(GL_QUADS,0,numParticles*4);
 		glEnd();
		star.Draw();
		for (int i=0;i<13;i++)
		{
			spark[i].Draw();
		}*/
		glDisable(GL_TEXTURE_2D);
	}
}


//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
// Called by Windows when it receives the WM_SIZE message.
// Put any code needed here to recalc the viewing volume and
// viewport info. For a screen saver, this only occurs once.
void GLResize(GLsizei w, GLsizei h)
{
	if( h == 0 )
		h = 1;
	// Set viewport to our dimensions.
	glViewport( 0, 0, w, h);
	sys_glWidth = (float) w;
	sys_glHeight = (float) h;
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-0.5,sys_glWidth+0.5,-0.5,sys_glHeight+0.5);
	glMatrixMode(GL_MODELVIEW);
	//glScissor(0,0,(int) sys_glWidth,(int) sys_glHeight);
	//glEnable(GL_SCISSOR_TEST);
}

